NetlifyキラーのVercelでウェブサイトをホストしたら簡単すぎて笑顔になった
最近話題のVercelを試してみました。競合のNetlifyと同様に、ビルドとホスティング他をまとめてやってくれます。Netlifyと比べて1人で開発をするならほぼフル機能が使えますし、無料プランのままでも100回/日までデプロイできるのが利点です。
前提
Next.jsと親和性の高いVercelですが、今回アプリはGatsby + Contentfulで構築しています。
詳しくは過去に書いた記事がありますので、下記の「1. Contentfulの準備」「2. Gatsbyアプリの立ち上げ」を参考にしてください。
また、Githubリポジトリを作成し、masterにソースコードをプッシュしておきます。
Vercelにアプリをデプロイする
https://vercel.comにアクセスし、「Start Deploying」から進むのですが、次のページでアプリをビルドするGitリポジトリを聞かれます。話が早いですね。
その後進んでいくと、デプロイ直前に環境変数を入力できます。
今回はアプリをビルドする際にContentfulから記事を取得しますので、ContentfulのAPIキーを環境変数として登録します。ここは適宜自分の環境に合わせて追加して下さい。
「Deploy」をクリックすると、Vercelがビルドを開始してくれます。
無事ビルドとデプロイが成功するとVercelから祝われます。やったね。
これでVercelが gatsby-blog-pn9ehiwtd.vercel.appのようなパブリックドメインでアプリを立ち上げてくれます。
以上、めちゃくちゃ簡単にアプリがローンチできました。
次回以降リポジトリのソースコードが更新された際も自動で同じプロセスを実行してくれます。
コンタクトフォームをつけてみる
デプロイだけだと笑ってしまうほど簡単すぎるので、ついでにコンタクトフォームを作ってみます。
今回はフォームのバックエンドを提供してくれるFormspreeというサービスを使ってみます。
Google Sheets, MailChimp, Slackなどのサードパーティと連携でき、スパム対策もしてくれます。50件までの問い合わせなら無料で利用できます。
ステップ1: Formspreeに登録する
下記のページからFormspreeに登録します。
https://formspree.io/create/zeit
ZEITはVercelの前のサービス名ですので気にしなくてOK。
登録が完了するとエンドポイントが発行されます。後ほど使うのでURLをコピーしておきます。
ステップ2: アプリ側でフォームの構築
HTTPクライアントであるaxiosをインストールします。
$ npm install axios
フォームコンポーネントを作成します。
src/components/contactForm.js
import React, { useState } from 'react'
import axios from 'axios'
export default () => {
const [status, setStatus] = useState({
submitted: false,
submitting: false,
info: { error: false, msg: null },
})
const [inputs, setInputs] = useState({
email: '',
message: '',
})
const handleServerResponse = (ok, msg) => {
if (ok) {
setStatus({
submitted: true,
submitting: false,
info: { error: false, msg: msg },
})
setInputs({
email: '',
message: '',
})
} else {
setStatus({
info: { error: true, msg: msg },
})
}
}
const handleOnChange = (e) => {
e.persist()
setInputs((prev) => ({
...prev,
[e.target.id]: e.target.value,
}))
setStatus({
submitted: false,
submitting: false,
info: { error: false, msg: null },
})
}
const handleOnSubmit = (e) => {
e.preventDefault()
setStatus((prevStatus) => ({ ...prevStatus, submitting: true }))
axios({
method: 'POST',
url: 'https://formspree.io/f/XXXXXXXX',
data: inputs,
})
.then((response) => {
handleServerResponse(
true,
'Thank you, your message has been submitted.'
)
})
.catch((error) => {
handleServerResponse(false, error.response.data.error)
})
}
return (
<main
style={{
margin: `0 auto`,
width: 500,
padding: `1.45rem 1.0875rem`,
}}
>
<h1>Sample Form</h1>
<form onSubmit={handleOnSubmit}>
<div style={{margin: `20px auto`}}>
<label htmlFor="email" style={{width: 100, display: `inline-block`}}>Email</label>
<input
id="email"
type="email"
name="_replyto"
onChange={handleOnChange}
required
value={inputs.email}
/>
</div>
<div style={{margin: `20px auto`,}}>
<label htmlFor="message" style={{width: 100, display: `inline-block`}}>Message</label>
<textarea
id="message"
name="message"
onChange={handleOnChange}
required
value={inputs.message}
/>
</div>
<div>
<button type="submit" disabled={status.submitting}>
{!status.submitting
? !status.submitted
? 'Submit'
: 'Submitted'
: 'Submitting...'}
</button>
</div>
</form>
{status.info.error && (
<div className="error">Error: {status.info.msg}</div>
)}
{!status.info.error && status.info.msg && <p>{status.info.msg}</p>}
</main>
)
}
上記で注意する点として、
axios({
method: 'POST',
url: 'https://formspree.io/f/XXXXXXXX',
data: inputs,
})
url
に先ほどFormspreeで生成されたエンドポイントURLを入力します。
ちなみにFormspreeの便利な機能として、emailフォームにname="_replyto"
属性を付与しておくと、問い合わせがあった際に管理者に届くメールに対し、"Reply to"として、入力されたメールアドレスを自動でセットしてくれます。問い合わせをしてくれたユーザーへの返信がちょっと簡単になる気の利いた機能です。
次に、フォームを呼び出すページを作成します。
src/pages/form.js
import React from 'react'
import ContactForm from "../components/contactForm";
export default function App() {
return (
<div>
<ContactForm />
</div>
)
}
ステップ3: Vercelにデプロイする
Vercelにデプロイします。といっても、Githubのmasterにpushするだけです。
htps://[アプリURL]/form にアクセスすると、フォームが出現します。
送信すると、管理者のメールアドレスに通知が届き、FormspreeのダッシュボードからSubmissionsが確認できます。
以上、静的サイト上にコンタクトフォームが非常に楽に実装できました。
さいごに
Jamstackのウェブサイトをこれ以上ないほど簡単にホストしてみました。
先日、CloudflareがJamstackサイトをホストするサービスを準備中というニュースもありましたし、今後こういったサービスが増えていくんでしょうかね。
参考URL
https://vercel.com/guides/deploying-gatsby-with-vercel
https://vercel.com/guides/deploying-react-forms-using-formspree-with-vercel